#pragma once

namespace Melting
{ 
	/**
		Template class for an instance of a IResource
	*/
	template < class TResource >
	class IResourceInstance
	{
	public:

		/// Is this ResourceUser already bound to a Resource ?
		inline bool									IsBoundToResource	( void ) const;						 
		/// Bind to a Resource !
		inline virtual void 						BindToResource		( TResource& _rResource );
		/// Unbind from its Resource !
		inline virtual void 						UnbindFromResource	( void );
		
		/// Get the ModelData this Model is bound to
		inline TResource*							GetResource			( void ) const;


		/// CTOR
		inline IResourceInstance( void );
		/// DTOR
		inline virtual ~IResourceInstance( void );

	protected:


		TResource*			mxpResource;		///< Parent Resource

	};

	// ------------------------------------------------------------------------------
	// CTOR
	// ------------------------------------------------------------------------------
	template< class TResource >
	IResourceInstance< TResource >::IResourceInstance( void )
	:	mxpResource ( nullptr )
	{ 
	}
	
	// ------------------------------------------------------------------------------
	// DTOR
	// ------------------------------------------------------------------------------
	template< class TResource >
	IResourceInstance< TResource >::~IResourceInstance( void )
	{ 		
		if( IsBoundToResource() )
		{
			UnbindFromResource();
		}
	}
	
	// ------------------------------------------------------------------------------
	// Is this model intialized?? (ie, is there any model loaded in it)
	// ------------------------------------------------------------------------------
	template< class TResource >
	bool IResourceInstance< TResource >::IsBoundToResource( void ) const		
	{ 
		return mxpResource != nullptr; 
	}
			 
	//------------------------------------------------------------------------------
	// Bind to a Resource !
	//------------------------------------------------------------------------------
	template< class TResource >
	void IResourceInstance< TResource >::BindToResource( TResource& _rResource )
	{
		//-------------------------------------
		// precondition 
		MB_ASSERT_NULL( GetResource() , "ResourcelInstance already bound to a Resource -> Unbind it first !\n" );
		//-------------------------------------
	
		mxpResource = & _rResource;
		mxpResource->RegisterInstance( *this );
		 
	}

	//------------------------------------------------------------------------------
	/// Unbind from its Resource !
	//------------------------------------------------------------------------------
	template< class TResource >
	void IResourceInstance< TResource >::UnbindFromResource	( void )
	{
		//-------------------------------------
		// precondition 
		MB_ASSERT_NOT_NULL( GetResource() , "ResourceInstance already unbound from its Resource ModelData !\n" );
		//-------------------------------------

		mxpResource->UnregisterInstance( *this );
		mxpResource = nullptr;
	}

	//------------------------------------------------------------------------------
	//------------------------------------------------------------------------------
	template< class TResource >
	TResource* IResourceInstance< TResource >::GetResource( void ) const
	{			
		return mxpResource;
	}
 
}